package org.aergia.vinny.gui.view;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.SortOrder;

import org.aergia.vinny.core.ApiResult;
import org.aergia.vinny.database.pojo.Card;
import org.aergia.vinny.database.pojo.VinnyUser;
import org.aergia.vinny.gui.controller.VinnyController;
import org.aergia.vinny.gui.types.ColumnDefinition;
import org.aergia.vinny.gui.util.DialogUtil;
import org.aergia.vinny.util.DateUtil;

public class CardPanel extends DatabasePojoPanel {

	private static final long serialVersionUID = 1L;

	/**
	 * @param controller
	 * @param user
	 */
	public CardPanel(final VinnyController controller, final VinnyUser user) {
		super(controller, user, new CardTableModel(controller), false);
	}

	@Override
	protected void addButtonActionPerformed(final ActionEvent event) {
		final CardEditor editor = new CardEditor(this.controller, this.user);
		final EditorDialog dialog = new EditorDialog(editor);

		if (dialog.isSaved()) {
			final CardTableModel volunteerTableModel = (CardTableModel) this.tableModel;
			volunteerTableModel.addNewRecord(editor.getCard());
			this.refresh();
		}
	}

	@Override
	protected void deleteButtonActionPerformed(final ActionEvent event) {
		final int selectedRow = this.getSelectedRow();
		if (selectedRow == -1) {
			return;
		}
		final CardTableModel cardTableModel = (CardTableModel) this.tableModel;
		final Card card = cardTableModel.getRecord(selectedRow);

		if (!DialogUtil.askQuestion(this, "Are you sure you want to disable " + card.getNumber(), "Disable Card")) {
			return;
		}

		card.setActive(false);
		final ApiResult<Card> result = this.controller.saveCard(card, this.user);
		if (!result.isError()) {
			cardTableModel.setRecord(selectedRow, card);
			this.tableModel.fireTableRowsUpdated(selectedRow, selectedRow);
			this.refresh();
		} else {
			DialogUtil.alert(this, result.getText(), "Error");
		}
	}

	@Override
	protected void editButtonActionPerformed(final ActionEvent event) {
		final int selectedRow = this.getSelectedRow();
		if (selectedRow == -1) {
			return;
		}
		final CardTableModel cardTableModel = (CardTableModel) this.tableModel;
		final Card card = cardTableModel.getRecord(selectedRow);
		final CardEditor editor = new CardEditor(this.controller, this.user, card);
		final EditorDialog dialog = new EditorDialog(editor);

		if (dialog.isSaved()) {
			cardTableModel.setRecord(selectedRow, card);
			this.tableModel.fireTableRowsUpdated(selectedRow, selectedRow);
			this.refresh();
		}
	}

	private static class CardTableModel extends DatabasePojoTableModel<Card> {

		private static List<ColumnDefinition> definitions;
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		static {
			CardTableModel.definitions = new ArrayList<ColumnDefinition>();
			CardTableModel.definitions.add(new ColumnDefinition("Active", Boolean.class));
			CardTableModel.definitions.add(new ColumnDefinition("Card Number", String.class, DatabasePojoTableModel.CARD_COLUMN_WIDTH, 0, SortOrder.ASCENDING));
			CardTableModel.definitions.add(new ColumnDefinition("First Name", String.class, DatabasePojoTableModel.NAME_COLUMN_WIDTH));
			CardTableModel.definitions.add(new ColumnDefinition("Last Name", String.class, DatabasePojoTableModel.NAME_COLUMN_WIDTH));
			CardTableModel.definitions.add(new ColumnDefinition("Start", String.class, DatabasePojoTableModel.DATE_COLUMN_WIDTH));
			CardTableModel.definitions.add(new ColumnDefinition("End", String.class, DatabasePojoTableModel.DATE_COLUMN_WIDTH));
			CardTableModel.definitions.add(new ColumnDefinition("Comment", String.class));
		}

		public CardTableModel(final VinnyController controller) {
			super(controller, CardTableModel.definitions);
		}

		@Override
		public Object getValueAt(final int rowIndex, final int columnIndex) {
			final Card card = this.records.get(rowIndex);
			switch (columnIndex) {
				case 0:
					return Boolean.valueOf(card.isActive());
				case 1:
					return card.getNumber();
				case 2:
					return card.getVolunteer().getFirstName();
				case 3:
					return card.getVolunteer().getLastName();
				case 4:
					return DateUtil.format(card.getStartDate());
				case 5:
					if (card.getEndDate() == null) {
						return "";
					}
					return DateUtil.format(card.getEndDate());
				case 6:
					return card.getComment() != null ? card.getComment() : "";
				default:
					return null;
			}
		}

		@Override
		protected void populateTable() {
			this.records.addAll(this.controller.getCards());
		}
	}

}
